﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace RelationExtraction
{

    public class Entity
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int Weight { get; set; }
    }

    public class Common
    {
        public static HashSet<String> functionWordsHash = new HashSet<String>();
        public static Dictionary<string, List<Entity>> SongEntityMap, PeopleEntityMap, MovieEntityMap;
        public static List<Rule> SongRules1, SongRules2, SongRules3, MovieRules1, MovieRules2;
        public static List<KeyRule> SongKeyRules1, SongKeyRules2, SongKeyRules3, DirectorKeyRules, StarKeyRules;

        public MainForm mainForm;
        public Common(MainForm form)
        {
            mainForm = form;
        }

        public static Dictionary<string, List<Entity>> ReadData(String fileName)
        {
            Dictionary<string, List<Entity>> entityMap = new Dictionary<string, List<Entity>>();
            StreamReader sr = new StreamReader(fileName, Encoding.Default);
            while (!sr.EndOfStream)
            {
                string context = sr.ReadLine();
                string[] strs = context.Split('\t');
                if (strs.Length == 4)
                {
                    Entity e = new Entity();
                    e.Id = strs[0];
                    e.Name = strs[1];
                    e.Description = strs[3];
                    e.Weight = 0;
                    if (entityMap.ContainsKey(e.Name))
                    {
                        entityMap[e.Name].Add(e);
                    }
                    else
                    {
                        List<Entity> entityList = new List<Entity>();
                        entityMap.Add(e.Name, entityList);
                        entityList.Add(e);
                    }
                }
            }
            return entityMap;
        }

        static void makeDic(string fileName)
        {
            int count = 0;
            int countall = 0;
            int countall2 = 0;
            StreamWriter sw = new StreamWriter(fileName, false, Encoding.Default);
            foreach (KeyValuePair<string, List<Entity>> item in SongEntityMap)
            {
                countall2 += item.Value.Count;
                if (item.Value.Count > 1)
                {
                    count++;
                    countall += item.Value.Count;
                }
                sw.WriteLine(item.Key + "@@sn");
            }
            sw.Flush();
            sw.Close();
            System.Console.WriteLine(count + "-" + countall + "-" + +countall * 1.0 / count + "-" + countall2);

        }

        public static List<KeyRule> ReadKeyRules(String filename)
        {
            List<KeyRule> rules = new List<KeyRule>();
            StreamReader sr = new StreamReader(filename, Encoding.Default);
            while (!sr.EndOfStream)
            {
                string context = sr.ReadLine();
                if (!String.IsNullOrEmpty(context))
                {
                    KeyRule rule = new KeyRule(context);
                    rules.Add(rule);
                }
            }
            return rules;
        }
        public static List<Rule> ReadRules(string fileName)
        {
            List<Rule> rules = new List<Rule>();
            StreamReader sr = new StreamReader(fileName, Encoding.Default);
            while (!sr.EndOfStream)
            {
                string context = sr.ReadLine();
                if (!String.IsNullOrEmpty(context))
                {
                    Rule rule = new Rule(context);
                    rules.Add(rule);
                }
            }
            return rules;
        }

        public static void keyTest(Dictionary<string, List<Entity>> SongEntityMap, Dictionary<string, List<Entity>> PeopleEntityMap)
        {
            List<KeyRule> rules = new List<KeyRule>();
            KeyRule a = new KeyRule("唱", 1);
            rules.Add(a);
            KeyRule b = new KeyRule("歌手", -1);
            rules.Add(b);
            KeyRule c = new KeyRule("演唱", -1);
            rules.Add(c);
            KeyRule d = new KeyRule("专辑", 1);
            rules.Add(d);
            //        String aa = "人人都爱80后    歌手：花儿乐队所属专辑：《花龄盛会》发行时间：2007-09-28 所属公司：金牌大风歌曲标签：华语流行。";
            //            Extraction.ExtractEntity(PeopleEntityMap, aa, rules);
            Extraction.ExtractOneEntityByDis(SongEntityMap, PeopleEntityMap, rules);
            Console.WriteLine("the number is" + a.count + ':' + b.count + "the sum finded:" + KeyRule.scount + "unfind:" + KeyRule.unscount);
        }

        private static void loadFunctionWords(String fileName)
        {
            String text = null;
            try
            {
                StreamReader sr = new StreamReader("FunctionWords.txt");
                text = sr.ReadToEnd();
                sr.Close();
            }
            catch (System.Exception ex)
            {
                throw new Exception("发生错误：无法打开虚词表");
            }
            char[] spliter = { '\n', '\r' };
            String[] functionWords = text.Split(spliter, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < functionWords.Length; i++)
            {
                functionWordsHash.Add(functionWords[i]);
            }
        }

        public void StartExtract(object typeObject)
        {
            int type = 1;
            int.TryParse(typeObject.ToString(), out type);
            string[] spliters = { "、", "和", "与", "携" };
            Extraction.listSpliter = new HashSet<string>(spliters);

            loadFunctionWords("FunctionWords.txt");

            SongEntityMap = ReadData("entity\\entity.song");
            PeopleEntityMap = ReadData("entity\\entity.people");
            MovieEntityMap = ReadData("entity\\entity.movie");

            SongRules1 = ReadRules("Rules\\songrule1.txt");//歌手
            SongRules2 = ReadRules("Rules\\songrule2.txt");//作词
            SongRules3 = ReadRules("Rules\\songrule3.txt");//作曲
            MovieRules1 = ReadRules("Rules\\movierule1.txt");//演员
            MovieRules2 = ReadRules("Rules\\movierule2.txt");//导演

            SongKeyRules1 = ReadKeyRules("Rules\\SongKeyRule1.txt");//歌手
            SongKeyRules2 = ReadKeyRules("Rules\\SongKeyRule2.txt");//作词
            SongKeyRules3 = ReadKeyRules("Rules\\SongKeyRule3.txt");//作曲
            DirectorKeyRules = ReadKeyRules("Rules\\DirectorKeyRule.txt");//导演
            StarKeyRules = ReadKeyRules("Rules\\StarKeyRule.txt"); //演员

            switch (type)
            {
                case 1:
                    Extraction.Extract(1, SongEntityMap, PeopleEntityMap, SongRules1, SongKeyRules1, "out1.txt", "演唱者");
                    break;
                case 2:
                    Extraction.Extract(2, SongEntityMap, PeopleEntityMap, SongRules2, SongKeyRules2, "out2.txt", "作词");
                    break;
                case 3:
                    Extraction.Extract(3, SongEntityMap, PeopleEntityMap, SongRules3, SongKeyRules3, "out3.txt", "作曲");
                    break;
                case 4:
                    Extraction.Extract(4, MovieEntityMap, PeopleEntityMap, MovieRules1, StarKeyRules, "out4.txt", "演员");
                    break;
                case 5:
                    Extraction.Extract(5, MovieEntityMap, PeopleEntityMap, MovieRules2, DirectorKeyRules, "out5.txt", "导演");
                    break;
                default:
                    break;
            }
            mainForm.Invoke((EventHandler)delegate
            {
                MessageBox.Show("关系抽取完成！");
                mainForm.buttonEx.Enabled = true;
                mainForm.UseWaitCursor = false;
            });
        }
    }
}
